// Copyright (c) MatrixFramework. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Matrix.ServiceCommunication.Services;

namespace Matrix.ServiceCommunication.Discovery.LoadBalancing;

/// <summary>
/// 轮询负载均衡器
/// </summary>
public class RoundRobinLoadBalancer : ILoadBalancer
{
    private readonly ConcurrentDictionary<string, int> _counters = new();

    public string StrategyName => "RoundRobin";

    public ServiceInstance Select(IList<ServiceInstance> instances)
    {
        if (instances == null || !instances.Any())
        {
            throw new ArgumentException("实例列表不能为空", nameof(instances));
        }

        var healthyInstances = instances.Where(i => i.Healthy && i.Enabled).ToList();
        if (!healthyInstances.Any())
        {
            throw new InvalidOperationException("没有可用的健康实例");
        }

        var serviceName = healthyInstances.First().ServiceName;
        var counter = _counters.GetOrAdd(serviceName, _ => 0);

        lock (_counters)
        {
            var index = counter % healthyInstances.Count;
            _counters[serviceName] = counter + 1;
            return healthyInstances[index];
        }
    }
}